package pt.utl.ist.isr.livetrack.server.impl;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import pt.utl.ist.isr.livetrack.server.interfaces.Perimeter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.apache.log4j.Logger;
import pt.utl.ist.isr.livetrack.server.DistributionUtils;
import pt.utl.ist.isr.livetrack.server.interfaces.Zone;

/**
 *
 * @author David Miguel Antunes <davidmiguel [ at ] antunes.net>
 */
public class PerimeterImpl implements Perimeter {

    private static final Logger logger = Logger.getLogger(PerimeterImpl.class);
    private Map<String, Zone> zones = new HashMap<String, Zone>();
    private Map<Long, String> camZoneMap = new HashMap<Long, String>();
    private String world;

    public PerimeterImpl() {
    }

    @Override
    public Map<String, Zone> getZones() {
        return DistributionUtils.proxyMap(zones);
    }

    public Map<String, Zone> getZonesLocal() {
        return zones;
    }

    @Override
    public Map<Long, String> getCamZoneMap() {
        return DistributionUtils.proxyMap(camZoneMap);
    }

    public Map<Long, String> getCamZoneMapLocal() {
        return camZoneMap;
    }

    @Override
    public Zone getWorld() {
        return DistributionUtils.proxyObj(zones.get(world));
    }

    public Zone getWorldLocal() {
        return zones.get(world);
    }

    @Override
    public Zone newZone(String id, String name) {
        Zone zone = new ZoneImpl(id, name);
        zones.put(id, zone);
        return DistributionUtils.proxyObj(zone);
    }

    @Override
    public void connect(String z1, String z2) {
        zones.get(z1).getConnections().add(z2);
        zones.get(z2).getConnections().add(z1);
    }

    @Override
    public void disconnect(String z1, String z2) {
        zones.get(z1).getConnections().remove(z2);
        zones.get(z2).getConnections().remove(z1);
    }

    @Override
    public void deleteZone(String id) {
        zones.remove(id);
        for (Long cam : new HashSet<Long>(camZoneMap.keySet())) {
            if (zones.get(camZoneMap.get(cam)).getId().equals(id)) {
                camZoneMap.remove(cam);
            }
        }
    }

    public void writeToFile(XMLEncoder encoder) {
        encoder.writeObject(zones);
        encoder.writeObject(camZoneMap);
        encoder.writeObject(world);
    }

    public static PerimeterImpl createFromFile(XMLDecoder decoder) {
        PerimeterImpl p = new PerimeterImpl();
        p.zones = (Map<String, Zone>) decoder.readObject();
        p.camZoneMap = (Map<Long, String>) decoder.readObject();
        p.world = (String) decoder.readObject();
        return p;
    }
}
